home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 November: Tool Chest / Dev.CD Nov 98 TC.toast / Sample Code / Devices / ATA Demo / ATA Demo.c < prev    next >
Encoding:
Text File  |  1998-07-14  |  19.8 KB  |  659 lines  |  [TEXT/CWIE]

  1. /*/*************************************************************************
  2. **    Apple Macintosh Developer Technical Support
  3. **
  4. **    Macintosh ATA Manager Sample 
  5. **
  6. **    by Vinne Moscaritolo, <vinnie@apple.com>
  7. **    Apple Developer Technical Support 
  8. **
  9. **  Created from as much sample code I could find.
  10. **  with much help from Gary Wilkinson, Rich Schnell and  Martin Minow
  11. **
  12. **  " Good Artists Imitate, Great Artist Steal "
  13. **
  14. **    File:        ATA Demo.c
  15. **
  16. **    Copyright © 1996, 1997, 1998 Apple Computer, Inc.
  17. **    All rights reserved.
  18. **
  19. **    Modifications:
  20. **        980625    Vin        Buffer was still the incorrect size in 
  21. **                        DisplayATADriveIdentity routine.
  22. **                        Buffer needs to be 256 words (for 512 bytes long). 
  23. **                        Drive identify just assumes you have allocated a
  24. **                        512 byte buffer and writes it accordingly.  In
  25. **                        this case it overwrites the end of the array.
  26. **
  27. **                        Modified to CW Pro 3 and its headers
  28. **
  29. **
  30. **        971005    BLoB    Buffer was incorrect size in 
  31. **                        DisplayATADriveIdentity routine.
  32. **                        Modified to CW Pro 1 and its headers
  33. **                        Added Metrowerks SIOUX specific stuff
  34. **                        Created Fat application
  35. **                        Realized that the words come back swapped; 
  36. **                        adjusted for this in the DumpFormatedBuffer routine.
  37. **
  38. **    You may incorporate this sample code into your applications without
  39. **    restriction, though the sample code has been provided "AS IS" and the
  40. **    responsibility for its operation is 100% yours.  However, what you are
  41. **    not permitted to do is to redistribute the source as "DSC Sample Code"
  42. **    after having made changes. If you're going to re-distribute the source,
  43. **    we require that you make it clear in the source that the code was
  44. **    descended from Apple Sample Code, but that you've made changes.
  45. **
  46. **************************************************************************/
  47.  
  48.  
  49.  
  50. //------------------------------------------------------------------------------------
  51. #pragma mark Includes
  52. //------------------------------------------------------------------------------------
  53. #include <stdio.h>
  54. #include <stdlib.h>
  55. #include <ATA.h>
  56. #ifdef __MWERKS__
  57.     #include <SIOUX.h>
  58. #endif
  59. #include "ata_powerpc.h"
  60. //------------------------------------------------------------------------------------
  61. #pragma mark Defines
  62. //------------------------------------------------------------------------------------
  63.  
  64. //
  65. // Identifies the bus protocol type.
  66. //
  67.  
  68. enum {
  69.     kDevUnknown        =    0,
  70.     kDevATA            =    1,
  71.     kDevATAPI        =    2,
  72.     kDevPCMCIA        =    3
  73. };
  74.  
  75. //
  76. // Identifies the Socket type.
  77. //
  78. enum {
  79.     kSocketUnknown        =    0,
  80.     kSocketInternal        =    1,
  81.     kSocketMediaBay        =    2,
  82.     kkSocketPCMCIA        =    3
  83. };
  84.  
  85. //------------------------------------------------------------------------------------
  86. #pragma mark Macros
  87. //------------------------------------------------------------------------------------
  88.  
  89. #define CLEAR(what) do {                        \
  90.         register Ptr        _ptr = (Ptr) &what;    \
  91.         register Size        _len = sizeof what;    \
  92.         for (; _len > 0; --_len)                    \
  93.             *_ptr++ = 0;                        \
  94.     } while (0)
  95.  
  96. #define IF_ERROR(_err_,_str_) if (_err_ != noErr) { printf(_str_); return (_err_); }
  97.  
  98.  
  99. //------------------------------------------------------------------------------------
  100. #pragma mark -
  101.  
  102. //------------------------------------------------------------------------------------
  103. #pragma mark Identify Drive Info
  104. //------------------------------------------------------------------------------------
  105.  
  106. //
  107. //  Bit fields returned from Identify Drive command
  108. //
  109. enum {
  110.     magdrv_bit        =    15,            /* WORD 0: bit number of mag drive indicator    */
  111.     rcd_bit            =    7,            /* WORD 0: bit number of removable indicator    */
  112.     fixed_bit        =    6,            /* WORD 0: bit number of fixed disk indicator    */
  113.  
  114.     lbamode_bit        =    9,            /* bit number of lba support indicator            */
  115.     iordy_bit        =    11,            /* bit number of IORDY support indicator        */
  116.     extvalid_bit    =    1,            /* bit number of valid extension word            */
  117.     mode3_bit        =    0,            /* WORD 64: bit number of mode 3 support        */
  118.     
  119.     kMagDrv            =    1 << magdrv_bit,    /* Bit 15 = 0 -> a magnetic drive        */
  120.     kRemovable        =    1 << rcd_bit,        /* Bit 7 != 0 -> removable cartridge    */
  121.     kFixed            =    1 << fixed_bit,        /* Bit 6 != 0 -> indicates fixed drive    */
  122.     kLBAMode        =    1 << lbamode_bit,    /* LBA support indicator                */
  123.     kIORDY            =    1 << iordy_bit,        /* IORDY support indicator                */
  124.     kExtValid        =    1 << extvalid_bit,    /* Extension word valid                    */
  125.     MODE3BIT        =    1 << mode3_bit        /* mode 3 bit in word 64 of ident data    */
  126. };
  127.  
  128. //
  129. // This is returned by the device in response to an IDENTIFY command (512 bytes).
  130. //
  131. typedef    struct IdentifyBlock {    /* Structure of Identify data                        */
  132.     short    Signature;            /* Word 00: Constant value                            */
  133.     short    NumCyls;            /* Word 01:    Number of cylinders (default mode)            */
  134.     short    RSVD0;                /* Word 02:    Constant value of 0                        */
  135.     short    NumHds;                /* Word 03:    Number of heads (default mode)            */
  136.     short    TrkBytes;            /* Word 04:    Number of unformatted bytes/track        */
  137.     short    SecBytes;            /* Word 05:    Number of unformatted bytes/sector        */
  138.     short    NumSecs;            /* Word 06:    Number of sectors/track                    */
  139.     short    VU0;                /* Word 07:    Vendor unique                            */
  140.     short    VU1;                /* Word 08:    Vendor unique                            */
  141.     short    VU2;                /* Word 09:    Vendor unique                            */
  142.     short    Serial[10];            /* Word 10-19:    Serial Number (right-justified)        */
  143.     short    BufType;            /* Word 20:    Buffer Type                                */
  144.     short    BufSize;            /* Word 21:    Buffer size in 512 byte increments        */
  145.     short    NumECC;                /* Word 22:    Number of ECC bytes                        */
  146.     short    FirmRev[4];            /* Word 23-26:    Firmware revision (left-justified)    */
  147.     short    ModelNum[20];        /* Word 27-46:    Model number (left-justified)        */
  148.     short    MultCmds;            /* Word 47:    R/W multiple commands not impl = 0        */
  149.     short    DblXferFlag;        /* Word 48:    Double transfer flag                    */
  150.     short    Capabilities;        /* Word 49: LBA, DMA, IORDY support indicator        */
  151.     short    Reserved1;            /* Word 50: Reserved                                */
  152.     short    PIOTiming;            /* Word 51: PIO transfer timing mode                */
  153.     short    DMATiming;            /* Word 52:    DMA transfer timing mode                */
  154.     short    Extension;            /* Word 53: extended info support                    */
  155.     short    CurCylinders;        /* Word 54: number of current cylinders                */
  156.     short    CurHeads;            /* Word 55: number of current heads                    */
  157.     short    CurSPT;                /* Word 56: number of current sectors per track        */
  158.     short    CurCapacity[2];        /* Word 57-58: current capacity in sectors            */
  159.     short    MultSectors;        /* Word 59: Multiple sector setting                    */
  160.     short    LBACapacity[2];        /* Word 60-61: total sectors in LBA mode            */
  161.     short    SWDMA;                /* Word 62: single word DMA support                    */
  162.     short    MWDMA;                /* Word 63: multi word DMA support                    */
  163.     short    APIOModes;            /* Word 64:    Advanced PIO Xfr mode supported            */
  164.     short    MDMATiming;            /* Word 65:    Minimum Multiword DMA Xfr Cycle            */
  165.     short    RDMATiming;            /* Word 66:    Recommended Multiword DMA Cycle            */
  166.     short    MPIOTiming;            /* Word 67:    Min PIO XFR Time W/O Flow Control        */
  167.     short    PIOwRDYTiming;        /* Word 68:    Min PIO XFR Time with IORDY flow ctrl    */
  168.     short    Reserved[187];        /* Word 69-255: Reserved                            */
  169. } IdentifyBlock;
  170.  
  171. //
  172. // The following structure and table simplifies the formatting.
  173. //
  174. enum {
  175.     kEndOfTable = 0,            /* Marker                                            */
  176.     kDecimal,                    /* Signed integer (two words are high..low)            */
  177.     kHex,                        /* Bitfield                                            */
  178.     kLeftJust,                    /* Ascii, left-justified, space padded                */
  179.     kRightJust                    /* Ascii, right-justified, space padded                */
  180. };
  181. struct FormatTable {
  182.     short        firstWord;        /* First word in IdentifyBlock cast to short vector    */
  183.     short        lastWord;        /* Last word in IdentifyBlock cast to short vector    */
  184.     short        format;            /* Format from above enum                            */
  185.     const char    *label;            /* Text to display                                    */
  186. };
  187.  
  188. typedef struct FormatTable FormatTable, *FormatTablePtr;
  189.  
  190. FormatTable kIdentFormat[] = {
  191.     {     0,     0, kHex,        "Configuration word"                        },
  192.     {     1,     1,    kDecimal,    "Cylinders"            },
  193.     {     3,     3,    kDecimal,    "Heads"                },
  194.     {     4,     4,    kDecimal,    "Bytes/Track"            },
  195.     {     5,     5,    kDecimal,    "Bytes/Sector (0 = 512 bytes)"        },
  196.     {     5,     5,    kDecimal,    "Sectors/Track"        },    /* 35 */
  197.     {     7,     9,    kHex,        "Vendor Unique (word 7..9)"                    },
  198.     {    10,    19,    kRightJust,    "Serial Number"                                },
  199.     {    20,    20,    kHex,        "Buffer Type"                                },
  200.     {    21,    21,    kDecimal,    "Buffer size in 512 byte increments"        },
  201.     {    22,    22,    kDecimal,    "Number of ECC bytes available"                },
  202.     {    23,    26,    kLeftJust,    "Firmware Revision"                            },
  203.     {    27,    46,    kLeftJust,    "Model Number"                                },
  204.     {    47,    53,    kHex,        "Capability Flags (word 47..53)"            },
  205.     {    54,    54,    kDecimal,    "Cylinders (current mode)"        },
  206.     {    55,    55,    kDecimal,    "Heads (current mode)"            },
  207.     {    56,    56,    kDecimal,    "Sectors/Track (current mode)"        },
  208.     {    57,    58,    kDecimal,    "Current Capacity in Sectors"                },
  209.     {    59,    59,    kHex,        "Multiple Sector Capability Flag"            },
  210.     {    60,    61,    kDecimal,    "Current User-addressable Sectors"            },
  211.     {    62,    62,    kHex,        "Single Word DMA Transfer Mode Flags"        },
  212.     {    63,    63,    kHex,        "Multiword DMT Transfer Mode Flags"            },
  213.     {     0,  0,    kEndOfTable,""                                            }
  214. };
  215.  
  216.  
  217.  
  218. //------------------------------------------------------------------------------------
  219. #pragma mark Prototypes
  220. //------------------------------------------------------------------------------------
  221.  
  222. Boolean     ATAManagerPresent    (void);
  223. Boolean     ATAHardwarePresent    (void);
  224. Boolean     TrapAvailable        (short theTrap);
  225. void         PrintNumVersion        (char *label, NumVersion version );
  226. OSErr         DisplayATAManagerInquiryInfo (void);
  227.  
  228. OSErr         ScanATABusses         (void);
  229. OSErr         DisplayATADriveIdentity (UInt32 deviceID );
  230. void        DumpRawBuffer        ( UInt8 *bufferPtr, int length );
  231. void        DumpFormatedBuffer    (void* p, const  FormatTablePtr formatPtr);
  232. char*        DrvrRefToName        (short refNum);
  233.  
  234.  
  235.  
  236. //------------------------------------------------------------------------------------
  237. #pragma mark -
  238.  
  239.  
  240. // ---------------------------------------------------------------------------
  241. void     main     (void)
  242. // ---------------------------------------------------------------------------
  243. {
  244.     OSErr            status;
  245.  
  246. #ifdef __MWERKS__
  247.     SIOUXSettings.asktosaveonclose = false;
  248. #endif
  249.  
  250.     printf("Macintosh ATA Manager Sample\n\n");
  251.  
  252. // Check for ATA Hardware 
  253. // you should do this before calling the ATAManager, since some early ROMS
  254. // could indicate an ATA manager without the proper HW, thus casing a crash.
  255.     if (ATAHardwarePresent() == FALSE) {
  256.         printf("ATA Hardware is not present on this system\n");
  257.         exit(EXIT_FAILURE);
  258.     }
  259.  
  260. // Check for ATA Manager
  261.     if (ATAManagerPresent() == FALSE) {
  262.         printf("ATA Manager is not present on this system\n");
  263.         exit(EXIT_FAILURE);
  264.     }
  265.         
  266. // Display ATA Manager Info
  267.     status = DisplayATAManagerInquiryInfo();
  268.     if (status != noErr) {
  269.         printf("Cannot access ATA Manager: %d\n", (int) status);
  270.         exit(EXIT_FAILURE);
  271.     }
  272.     
  273. // Display ATA Device Info
  274.     status = ScanATABusses();
  275.     if (status != noErr) {
  276.         printf("Cannot access ATA Manager: %d\n", (int) status);
  277.         exit(EXIT_FAILURE);
  278.     }
  279. }
  280.  
  281.  
  282. // ---------------------------------------------------------------------------
  283. OSErr         DisplayATAManagerInquiryInfo (void)
  284. // ---------------------------------------------------------------------------
  285. //
  286. //  Display information about the ATA Manager
  287. //
  288. {
  289.     ataMgrInquiry    pb;
  290.     OSErr            status;
  291.  
  292.     CLEAR(pb);
  293.     
  294.     pb.ataPBFunctionCode =    kATAMgrManagerInquiry;
  295.     pb.ataPBVers =            kATAPBVers1;
  296.  
  297.     status = ataManager((ataPB*) &pb );
  298.     IF_ERROR(status, "ATA Manager Inquiry failed\n")
  299.  
  300.     printf("ATA Manager inquiry:\n");
  301.     PrintNumVersion("\tATA Manager Version:", pb.ataMgrVersion);
  302.     printf("\tBusses:\t\t%d\n\tDevices:\t%d\n",
  303.                 pb.ataBusCnt, pb.ataDevCnt);
  304.     printf("\tPIO Modes:\t%x\n\tDMA Modes:\t%d\n\tMulti DMA Modes:%x\n",
  305.                  pb.ataPioModes, pb.ataSingleDMAModes, pb.ataMultiDMAModes);
  306.     printf("-----------------------------------------\n\n");    
  307.     return (status);
  308. }
  309.  
  310.  
  311. // ---------------------------------------------------------------------------
  312. OSErr         ScanATABusses (void)
  313. // ---------------------------------------------------------------------------
  314. //
  315. //  Display information about the ATA Busses
  316. //
  317. {
  318.     ataDrvrRegister        pb;
  319.     OSErr                status;
  320.  
  321. // Get first device ID (yes you have to do this once)
  322.     CLEAR(pb);
  323.     pb.ataPBFunctionCode     =    kATAMgrFindDriverRefnum;
  324.     pb.ataPBVers            =    kATAPBVers1;
  325.     pb.ataPBDeviceID         =     (UInt32)0x0000ffff;
  326.     status                     =     ataManager((ataPB*) &pb );
  327.  
  328. // loop through devices
  329.     for    (pb.ataPBDeviceID = (UInt32) pb.ataDeviceNextID;
  330.          pb.ataPBDeviceID != 0xff;
  331.          pb.ataPBDeviceID = (UInt32) pb.ataDeviceNextID)
  332.         {             
  333.             status = ataManager((ataPB*) &pb );
  334.             IF_ERROR(status, "ATA Find Driver failed\n")
  335.             
  336.             printf("Device %d %#s\n", pb.ataPBDeviceID, DrvrRefToName(pb.ataDrvrRefNum) );
  337.             DisplayATADriveIdentity(pb.ataPBDeviceID);
  338.             
  339.         printf("-----------------------------------------\n\n");    
  340.         };    
  341.     
  342.     printf("\n");    
  343.     return (status);
  344. }
  345.  
  346.  
  347.  
  348. // ---------------------------------------------------------------------------
  349. OSErr         DisplayATADriveIdentity (UInt32 deviceID)
  350. // ---------------------------------------------------------------------------
  351. //
  352. //  Display information about the ATA Identify Info
  353. //
  354. {
  355.     ataIdentify            pb;
  356.     ataDevConfiguration    pb1;
  357.     
  358.     UInt16        buffer[256];
  359.     OSErr        status;
  360.     
  361.  
  362. // Get Driver Configuration
  363.     CLEAR(pb1);
  364.     pb1.ataPBFunctionCode     =    kATAMgrGetDrvConfiguration;
  365.     pb1.ataPBVers            =    kATAPBVers2;
  366.     pb1.ataPBDeviceID         =    deviceID;
  367.     
  368.     status = ataManager((ataPB*) &pb1 );
  369.     IF_ERROR(status, "ATA GetDrvConfiguration failed\n")
  370.  
  371.  
  372. // Setup Identify block;
  373.     CLEAR(pb);
  374.     pb.ataPBFunctionCode     =    kATAMgrDriveIdentify;
  375.     pb.ataPBVers            =    kATAPBVers1;
  376.     pb.ataPBDeviceID        =    deviceID;
  377.      pb.ataPBFlags             =     mATAFlagIORead + mATAFlagByteSwap ;
  378.      
  379.      if(pb1.ataDeviceType == kDevATAPI) pb.ataPBFlags += mATAFlagProtocol1;
  380.      
  381.     pb.ataPBTimeOut            =    100;
  382.     pb.ataPBBuffer            =    (void*) buffer;
  383.     
  384.     status = ataManager((ataPB*) &pb );
  385.     IF_ERROR(status, "ATA DriveIdentify failed\n")
  386.  
  387.     printf("Configuration: (");
  388.  
  389.     switch(pb1.ataDeviceType){
  390.         case kDevUnknown:    
  391.                         printf("Unknown protocol"); 
  392.                         break;
  393.         
  394.         case kDevATA:
  395.                         printf("ATA"); 
  396.                         break;
  397.                              
  398.         case kDevATAPI:    
  399.                         printf("ATAPI"); 
  400.                         break;
  401.                         
  402.         case kDevPCMCIA:    
  403.                         printf("PCMCIA"); 
  404.                         break;
  405.     }
  406.     
  407.     switch(pb1.ataSocketType){
  408.         case kSocketUnknown:    
  409.                         printf(", Unknown Socket"); 
  410.                         break;
  411.         
  412.         case kSocketInternal:
  413.                         printf(", Internal"); 
  414.                         break;
  415.                              
  416.         case kSocketMediaBay:    
  417.                         printf(", Media Bay"); 
  418.                         break;
  419.                         
  420.         case kkSocketPCMCIA:    
  421.                         printf(", PCMCIA, Vcc=%d, Vpp1=%d, Vpp2=%d", 
  422.                                         pb1.atapcVcc, pb1.atapcVpp1,pb1.atapcVpp2); 
  423.                         break;
  424.     }
  425.  
  426.     printf(")\n");
  427.  
  428.     DumpFormatedBuffer(buffer, kIdentFormat);
  429. };
  430.  
  431.  
  432.  
  433.  
  434. // ---------------------------------------------------------------------------
  435. Boolean     ATAManagerPresent    (void)
  436. // ---------------------------------------------------------------------------
  437. //
  438. // returns true if this machine has the ata manager
  439. //
  440. {
  441.         return (TrapAvailable(kATATrap));
  442. }
  443.  
  444. // ---------------------------------------------------------------------------
  445. Boolean     ATAHardwarePresent        (void)
  446. // ---------------------------------------------------------------------------
  447. //
  448. // returns true if this machine has ata hardware
  449. //
  450. {
  451.     UInt16    configFlags;
  452.  
  453.     // Hardware configuration flags
  454.     configFlags = LMGetHWCfgFlags();
  455.     
  456.     return (configFlags & 0x0080);
  457. }
  458.  
  459. //------------------------------------------------------------------------------------
  460. #pragma mark -
  461.  
  462. #define NumToolboxTraps() (                                \
  463.         (NGetTrapAddress(_InitGraf, ToolTrap)            \
  464.                 == NGetTrapAddress(0xAA6E, ToolTrap))    \
  465.             ? 0x200 : 0x400                                \
  466.     )
  467. #define GetTrapType(theTrap) (                            \
  468.         (((theTrap) & 0x800) != 0) ? ToolTrap : OSTrap    \
  469.     )
  470.  
  471. // ---------------------------------------------------------------------------
  472. Boolean     TrapAvailable        (short theTrap)
  473. // ---------------------------------------------------------------------------
  474. // (see Inside Mac VI 3-8)
  475. {
  476.         TrapType                trapType;
  477.         
  478.         trapType = GetTrapType(theTrap);
  479.         if (trapType == ToolTrap) {
  480.             theTrap &= 0x07FF;
  481.             if (theTrap >= NumToolboxTraps())
  482.                 theTrap = _Unimplemented;
  483.         }
  484.         return (
  485.             NGetTrapAddress(theTrap, trapType)
  486.             != NGetTrapAddress(_Unimplemented, ToolTrap)
  487.         );
  488. }
  489.  
  490. // ---------------------------------------------------------------------------
  491. void         PrintNumVersion        (char *label, NumVersion version )
  492. // ---------------------------------------------------------------------------
  493. //
  494. //    Decode version number info
  495. //
  496. {
  497.     char            *stage;
  498.  
  499.     switch (version.stage) {
  500.     case developStage:    stage = "d";        break;
  501.     case alphaStage:    stage = "a";        break;
  502.     case betaStage:        stage = "b";        break;
  503.     case finalStage:    stage = "";            break;
  504.     default:            stage = "?";        break;
  505.     
  506.     }
  507.     printf("%s %d.%d.%d",
  508.         label,
  509.         version.majorRev,
  510.         (version.minorAndBugRev>>4), (version.minorAndBugRev & 0xf),
  511.         stage);
  512.     if(version.stage != finalStage) printf(".%d",version.nonRelRev);
  513.     
  514.     printf(" (hex %08lx)\n",    (* ((unsigned long *) &version)));
  515. }
  516.  
  517.  
  518.  
  519. // ---------------------------------------------------------------------------
  520. void        DumpFormatedBuffer    (void* p,  const FormatTablePtr format) 
  521. // ---------------------------------------------------------------------------
  522. //
  523. // Dump formatted buffer
  524. //
  525.  
  526. {    
  527.     unsigned short            *idInfo = p;
  528.          
  529.     register char            *charField;
  530.     register short            fieldLength;
  531.     register short            i;
  532.     register long            value;
  533.     register FormatTablePtr    formatPtr;
  534.     
  535. #define FORMAT    (*formatPtr)
  536.  
  537.     for (formatPtr = format; FORMAT.format != kEndOfTable; formatPtr++) {
  538.             printf("%35s", FORMAT.label);
  539.             switch (FORMAT.format) {
  540.             // Decimal values come as two words with the words swapped.
  541.             case kDecimal:
  542.                 value = 0;
  543.                 for (i = FORMAT.lastWord; i >= FORMAT.firstWord; i--) {
  544.                     value <<= 16;
  545.                     value += idInfo[i];
  546.                 }
  547.                 printf(" %lu", value);    // was %lu
  548.                 break;
  549.             case kHex:
  550.                 for (i = FORMAT.lastWord; i >= FORMAT.firstWord; i--) {
  551.                     value = idInfo[i];
  552.                     printf(" %04ld", value);
  553.                 }
  554.                 break;
  555.             case kLeftJust:
  556.                 charField = (char *) &idInfo[FORMAT.firstWord];
  557.                 fieldLength = (FORMAT.lastWord - FORMAT.firstWord + 1)
  558.                             * sizeof (unsigned short);
  559.                 /*
  560.                  * First scan for an unspecified field.
  561.                  */
  562.                 for (i = 0; i <= fieldLength; i++) {
  563.                     if (charField[i] != '\0')
  564.                         goto gotLeftJustField;
  565.                 }
  566.                 printf(" <not specified>");
  567.                 break;
  568. gotLeftJustField:
  569.                 for (i = fieldLength; i > 0; --i) {
  570.                     if (charField[i - 1] != ' ')
  571.                         break;
  572.                 }
  573.                 printf(" \"%.*s\"", (int) i, charField);
  574.                 break;
  575.             case kRightJust:
  576.                 charField = (char *) &idInfo[FORMAT.firstWord];
  577.                 fieldLength = (FORMAT.lastWord - FORMAT.firstWord + 1)
  578.                             * sizeof (unsigned short);
  579.                 /*
  580.                  * First scan for an unspecified field.
  581.                  */
  582.                 for (i = 0; i <= fieldLength; i++) {
  583.                     if (charField[i] != '\0')
  584.                         goto gotRightJustField;
  585.                 }
  586.                 printf(" <not specified>");
  587.                 break;
  588. gotRightJustField:
  589.                 for (i = 0; i < fieldLength; i++) {
  590.                     if (charField[i] != ' ')
  591.                         break;
  592.                 }
  593.                 printf(" \"%.*s\"", (int) (fieldLength - i), &charField[i]);
  594.                 break;
  595.             }
  596.             printf("\n");
  597.         }
  598. //        DumpRawBuffer( p,512);
  599. }    
  600.     
  601. // ---------------------------------------------------------------------------
  602. void        DumpRawBuffer        ( UInt8 *bufferPtr, int length )
  603. // ---------------------------------------------------------------------------
  604. //
  605. // Dump buffer
  606. //
  607.  
  608. {
  609.         register int            i;
  610.         int                        lineStart;
  611.         int                        lineLength;
  612.         short                    c;
  613.  
  614. #define kLineSize    16
  615.         for (lineStart = 0; lineStart < length; lineStart += lineLength) {
  616.             lineLength = kLineSize;
  617.             if (lineStart + lineLength > length)
  618.                 lineLength = length - lineStart;
  619.             printf("%03x %3d:", lineStart, lineStart);
  620.             for (i = 0; i < lineLength; i++)
  621.                 printf(" %02x", bufferPtr[lineStart + i] & 0xFF);
  622.             for (; i < kLineSize; i++)
  623.                 printf("   ");
  624.             printf("  ");
  625.             for (i = 0; i < lineLength; i++) {
  626.                 c = bufferPtr[lineStart + i] & 0xFF;
  627.                 if (c > ' ' && c < '~')
  628.                     printf("%c", c);
  629.                 else {
  630.                     printf(".");
  631.                 }
  632.             }
  633.             printf("\n");
  634.         }
  635. }
  636.  
  637.  
  638.         
  639. // ---------------------------------------------------------------------------
  640. char*        DrvrRefToName(short refNum)
  641. // ---------------------------------------------------------------------------
  642. //
  643. //  lookup driver name in table
  644. //
  645.  
  646. {
  647.         AuxDCEHandle*        UTable  = (AuxDCEHandle*) LMGetUTableBase();
  648.         DCtlPtr                dctl;
  649.         Ptr                    p;    
  650.         
  651.         if(!refNum) return ((char*) "\p<none>");
  652.  
  653.         dctl = (DCtlPtr) *UTable[~refNum];
  654.         p      =  dctl->dCtlDriver;
  655.         if( dctl->dCtlFlags  & 0x0040) p = (void*) *p;
  656.  
  657.         return  ( p?(char*) (p+18):(char*)"\p-Purged-");
  658. }
  659.